package com.shadowtorcher.stdisk.util;

import com.shadowtorcher.soulknife.SoulKnifeDB;
import com.shadowtorcher.soulknife.exception.BeanConfigErrorException;
import com.shadowtorcher.stdisk.bean.PhysicsFileBean;
import com.shadowtorcher.stdisk.bean.SharedFileBean;
import com.shadowtorcher.stdisk.bean.UserBean;

import javax.servlet.http.HttpSession;
import javax.xml.bind.DatatypeConverter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.SQLException;
import java.util.Random;
import java.util.StringJoiner;
import java.util.UUID;

public class StaticUtils {
    private static final String USER_STR = "com.shadowtorcher.stdisk.user";
    private static char charset[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

    // UUID 看起来像 550E8400-E29B-11D4-A716-446655440000
    public static String generatorStringUUID() {
        return UUID.randomUUID().toString();
    }

    public static UUID getUUID(String str) {
        return UUID.fromString(str);
    }

    public static UUID generatorUUID() {
        return UUID.randomUUID();
    }

    public static String getMd5(String str) {
        String ans = "null";
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.update(str.getBytes());
            ans = DatatypeConverter.printHexBinary(messageDigest.digest()).toUpperCase();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return ans;
    }

    public static String getEncodeUrl(String string) {
        String[] strings = string.split("/");
        StringJoiner stringJoiner = new StringJoiner("/");
        for (String str : strings) {
            try {
                stringJoiner.add(URLEncoder.encode(str, "utf-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return stringJoiner.toString();
    }

    /**
     * 生成分享代码
     *
     * @return 不会重复的 6 位代码，数字+大小写
     */
    public static String generatorShareCode() {
        final int SIZE = 6;
        try {
            StringBuffer code = new StringBuffer();
            while (code.length() < SIZE) {
                long randm = Math.abs(new Random().nextLong());
                while (randm != 0) {
                    int t = (int) (randm % charset.length);
                    code.append(charset[t]);
                    randm /= charset.length;
                }
            }
            if (!SoulKnifeDB.selectWhere("Url = ?", code.toString()).setClass(SharedFileBean.class).isEmpty()) {
                return generatorShareCode();
            } else {
                return code.substring(0, SIZE);
            }
        } catch (SQLException | BeanConfigErrorException e) {
            e.printStackTrace();
            return generatorStringUUID().replaceAll("-", "").substring(0, SIZE);
        }
    }

    public static UserBean getUser(HttpSession httpSession) {
        return (UserBean) httpSession.getAttribute(USER_STR);
    }

    public static void setUser(HttpSession httpSession, UserBean user) {
        httpSession.setAttribute(USER_STR, user);
    }

    public static void subReferenceCount(String uuid) throws SQLException, BeanConfigErrorException {
        operateReferenceCount(uuid, -1);
    }

    public static void addReferenceCount(String uuid) throws SQLException, BeanConfigErrorException {
        operateReferenceCount(uuid, +1);
    }

    private synchronized static void operateReferenceCount(String uuid, int i) throws SQLException, BeanConfigErrorException {
        PhysicsFileBean physicsFile = SoulKnifeDB.selectWhere("PhysicsFileID = ?", uuid).setClass(PhysicsFileBean.class).get(0);
        physicsFile.setReferenceCount(physicsFile.getReferenceCount() + i);
        SoulKnifeDB.updateWhere(physicsFile, "PhysicsFileID = ?", physicsFile.getPhysicsFileID()).setClass(PhysicsFileBean.class);
    }
}
